package com.example.cloud.service.system.impl;

import com.alibaba.fastjson.JSONArray;
import com.example.cloud.dao.system.OrganRepository;
import com.example.cloud.dao.mongdb.system.MongoOrganRepository;
import com.example.cloud.model.system.Organ;
import com.example.cloud.model.system.User;
import com.example.cloud.service.system.OrganService;
import com.example.cloud.utils.BusinessUtil;
import com.example.cloud.utils.RequestUtil;
import com.example.cloud.utils.TreeUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static java.util.stream.Collectors.toList;

/**
 * Created by wangtao on 2018/2/3.
 */
@Service
public class OrganServiceImpl implements OrganService {

    private static final Logger logger = Logger.getLogger(OrganServiceImpl.class);

    @Autowired
    private OrganRepository organRepository;

    @Autowired
    private MongoOrganRepository mongoOrganRepository;

    @Override
    public JSONArray createOrganTree(List<Organ> organs) {
        return TreeUtil.buildOrganTree(organs);
    }

    @Override
    public Organ findOneFromCache(Long id) {
        return mongoOrganRepository.findOne(id);
    }

    @Override
    public Organ findRootNode() {
        return mongoOrganRepository.findByLevelAndDeleteFlag(0, 0);
    }

    @Override
    public List<Organ> findChildren(Long parentId) {
        return mongoOrganRepository.findByParentIdAndDeleteFlag(parentId, 0);
    }

    @Override
    public List<Organ> findAllFromCache() {
        return mongoOrganRepository.findAll();
    }

    @Override
    public List<Organ> getOrganList(User user, Organ organ) {
        List<Long> ids = user.getOrgans().stream().map(Organ::getId).collect(toList());
        // 包含即删除
        if (ids.contains(organ.getId())) {
            // 待删除节点id
            List<Long> delIds = new ArrayList<Long>();
            delIds.add(organ.getId());
            // 递归子节点
            getChildNodesId(delIds, organ);
            // 递归父节点
            getParentNodesId(delIds, user, organ.getId(), organ.getParentId());
            List<Organ> list = user.getOrgans().stream().filter(userOrgan -> delIds.contains(userOrgan.getId())).collect(toList());
            if(!list.isEmpty()){
                user.getOrgans().removeAll(list);
            }
        } else {
            // 添加当前节点
            user.getOrgans().add(organ);
            // 添加父节点
            addParentNode(ids, user.getOrgans(), organ);
            // 添加子节点
            addChildNode(user.getOrgans(), organ);
        }
        return user.getOrgans();
    }

    /**
     * 递归追加父节点名称
     * @param name
     */
    @Override
    public void appendName(Long parentId, StringBuilder name) {
        if(parentId != null){
            Organ organ = mongoOrganRepository.findOne(parentId);
            if(organ != null){
                name.insert(0,organ.getOrganName());
                appendName(organ.getParentId(), name);
            }
        }
    }

    /**
     * 判断是否存在父节点
     * @param ids
     * @param organs
     * @param organ
     */
    public void addParentNode(List<Long> ids, List<Organ> organs, Organ organ) {
        Long parentId = organ.getParentId();
        if (parentId != null && !ids.contains(parentId)) {
            Organ parent = mongoOrganRepository.findOne(parentId);
            if(parent != null){
                organs.add(parent);
                addParentNode(ids, organs, parent);
            }
        }
    }

    /**
     * 判断是否存在子节点
     * @param organs
     * @param organ
     */
    public void addChildNode(List<Organ> organs, Organ organ) {
        organ.getChildren().stream().forEach(child -> {
            organs.add(child);
            addChildNode(organs, child);
        });
    }

    /**
     * 获取当前节点的父节点集合
     * @param ids
     * @param user
     * @param id
     * @param parentId
     */
    public void getParentNodesId(List<Long> ids, User user, Long id, Long parentId) {
        if(parentId != null){
            // 如果该节点能被删除，则继续往下递归
            boolean flag = user.getOrgans().stream().anyMatch(userOrgan -> parentId.equals(userOrgan.getParentId()) && !id.equals(userOrgan.getId()));
            if (!flag) {
                Organ organ = user.getOrgans().stream().filter(userOrgan -> parentId.equals(userOrgan.getId())).findFirst().get();
                if(organ != null && organ.getParentId() != null){
                    ids.add(organ.getId());
                    getParentNodesId(ids, user, organ.getId(), organ.getParentId());
                }
            }
        }
    }

    /**
     * 获取当前节点下所有子节点集合
     *
     * @return
     */
    public void getChildNodesId(List<Long> childIds, Organ organ) {
        organ.getChildren().stream().forEach(child -> {
            childIds.add(child.getId());
            getChildNodesId(childIds, child);
        });
    }

    @Override
    public void doSave(Organ organ) {
        // 保存实体
        if(organ.getId() == null){
            User user = RequestUtil.getLoginUser();
            organ.setAccountId(user.getAccountId());
        }
        BusinessUtil.appendRecord(organ);
        organRepository.save(organ);
        // 同步缓存
        mongoOrganRepository.save(organ);
    }

    @Override
    public void doDelete(Long id) {
        // 删除实体
        organRepository.delete(id);
        // 删除缓存
        mongoOrganRepository.delete(id);
    }

    @Override
    public void loadCache() {
        List<Organ> list = organRepository.findAll();
        if (!list.isEmpty()) {
            mongoOrganRepository.save(list);
            logger.info("*******************组织机构已全部同步缓存*******************");
        }
    }
}
